package com.zhuang.mycodeproject.delay;

import java.util.HashMap;
import java.util.concurrent.DelayQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

public class DelayQueueManager {
    private final static int DEFAULT_THREAD_NUM = 5;
    private static int thread_num = DEFAULT_THREAD_NUM;
    //任务map记录，通过该map，点测的时候查询延迟任务，进行相应的提前处理或取消延迟任务，key:data.getDeviceid()+"_"+data.getRoadid() 即设备id+“_”+光路/电路id
    public volatile HashMap<String, DelayTask> DELAY_TASK_MAP = new HashMap<>();
    //延迟时间,暂定3分钟
    public static final Integer DELAY_TIME=180;//单位秒
    // 固定大小线程池
    private ExecutorService executor;
    // 守护线程
    private Thread daemonThread;
    // 延时队列
    private DelayQueue<DelayTask<?>> delayQueue;
    //private static final AtomicLong atomic = new AtomicLong(0);
    //private final long n = 1;
    private static DelayQueueManager instance = new DelayQueueManager();

    private DelayQueueManager() {
        executor = Executors.newFixedThreadPool(thread_num);
        delayQueue = new DelayQueue<>();
        init();
    }

    public static DelayQueueManager getInstance() {
        return instance;
    }

    /**
     * 初始化
     */
    public void init() {
        daemonThread = new Thread(() -> {
            execute();
        });
        daemonThread.setName("DelayQueueMonitor");
        daemonThread.start();
    }

    private void execute() {
        while (true) {
           // Map<Thread, StackTraceElement[]> map = Thread.getAllStackTraces();
            //System.out.println(LocalDateTime.now()+">>>"+"当前存活线程数量:" + map.size());
            int taskNum = delayQueue.size();
           // System.out.println(LocalDateTime.now()+">>>"+"当前延时任务队列中数量:" + taskNum);
            try {
                // 从延时队列中获取任务
                DelayTask<?> delayOrderTask = delayQueue.take();
                if (delayOrderTask != null) {
                    Runnable task = delayOrderTask.getTask();
                    if (null == task) {
                        continue;
                    }
                    // 提交到线程池执行task
                    executor.execute(task);
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 添加任务
     *
     * @param task
     *
     *
     */
    public DelayTask put(DelayWorker task) {
        //@param time        延时时间
        long time=DELAY_TIME;
        //@param unit           时间单位
        TimeUnit unit = TimeUnit.SECONDS;
        // 获取延时时间
        long timeout = TimeUnit.NANOSECONDS.convert(time, unit);
        // 将任务封装成实现Delayed接口的消息体
        DelayTask<?> delayOrder = new DelayTask<>(timeout, task);
        // 将消息体放到延时队列中
        delayQueue.put(delayOrder);
        return  delayOrder;
    }

    /**
     * 删除任务
     *
     * @param task
     * @return
     */
    public boolean removeTask(DelayTask task) {

        return delayQueue.remove(task);
    }


    public static void main(String[] args) {
        //3、创建延迟任务
        DelayQueueManager manager = DelayQueueManager.getInstance();
        String id = "1";
        DelayWorker delayWorker = new DelayWorker(id);
        DelayTask delayTask = manager.put(delayWorker);

        //清除延迟任务
        manager.removeTask(delayTask);
    }
}
